﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using HighLowBase;
using HighLowBase.Entity;
using HighLowTriple7.Entity;

namespace HighLowTriple7
{
    class HiLoTriple7
    {
        #region Delegate
        public delegate void HiLoTriple7Event(int accountId, object msg, object tag);

        public delegate void HiLoTriple7JackpotEvent(int accountId, Triple7SessionInfo info);
        #endregion

        #region Event
        public event HiLoTriple7Event HiLoTriple7EventHandler;
        #endregion

        #region Properties
        public static GameBaseEntity GameTriple7 { get; set; }

        private Triple7Status _Status = Triple7Status.None;

        private int _CountSession = 0;
        private int _CountWin = 0;
        private int _CountConsecutiveWin = 0;

        private int _AccountId;
        private string _AccountName;
        private int _AccountTypeId;

        private long _SessionId;
        private int _AuBet;
        private int _AgBet;
        private int _AuCurrent;
        private int _AgCurrent;
        private int _CurrentExtraLife;
        private int _CurrentOutOf;
        private int _CurrentNudges;
        private int _CurrentFreeSpin;

        private int _UsedExtraLife = 0;
        private int _UsedOutOf = 0;
        private int _UsedNudges = 0;
        private int _UsedFreeSpin = 0;
        private int _Jackpot = 0;
        private int _Round = 0;

        private int _Column1Value = 6;
        private int _Column2Value = 7;
        private int _Column3Value = 8;

        private Random _Random = new Random();

        private int _ResultValue;

        private DateTime CreatedDate = DateTime.Now;

        public bool IsBusy { get; private set; }
        #endregion Properties

        #region Private method

        #region xu ly choi
        //------- Call by private method ------
        private void ClearProperties()
        {
            _Round = _AuBet = _AgBet = _AuCurrent = _AgCurrent = 0;
            _CurrentExtraLife = _CurrentOutOf = _CurrentNudges = _CurrentFreeSpin = 0;
            _UsedExtraLife = _UsedOutOf = _UsedNudges = _UsedFreeSpin = 0;
            _Jackpot = 0;
        }

        private int GetRandomForSession()
        {
            const int N = 10000000;
            int n = GameTriple7.MaximumValue - GameTriple7.MinimumValue + 1;
            n = _Random.Next(1 * N, n * N) % n + 1;
            return n + GameTriple7.MinimumValue - 1;
        }

        private void CreateRandomFor(out int value1, out int value2, out int value3)
        {
            value1 = GetRandomForSession();
            value2 = GetRandomForSession();
            value3 = GetRandomForSession();
        }

        private void LoadGame()
        {
            if (_Status == Triple7Status.LoadGame)
            {
                if (GameTriple7 == null)
                    throw new Exception("Quá trình tải game gặp sự cố. (Thông tin game = null)");
                else
                {
                    _Status = Triple7Status.LoadSession;
                }
            }
            else
            {
                throw new Exception("Trạng thái hiện tại không thể tải game. (CurrentStatus: " + _Status.ToString() + ")");
            }
        }

        private void LoadSession()
        {
            if (_Status == Triple7Status.LoadSession)
            {
                CreateRandomFor(out _Column1Value, out _Column2Value, out _Column3Value);

                SessionBaseEntity session = HiLoSession.LoadSession(GameTriple7.Id, _AccountId);
                if (session != null)
                {
                    this._SessionId = session.Id;
                    this._AuBet = (int)session.AuBet;
                    this._AgBet = (int)session.AgBet;
                    this._AuCurrent = (int)session.AuCurrent;
                    this._AgCurrent = (int)session.AgCurrent;
                    this._CurrentExtraLife = session.CurrentExtraLife;
                    this._CurrentOutOf = session.CurrentOutOf;
                    this._CurrentNudges = session.CurrentNudges;
                    this._CurrentFreeSpin = session.CurrentFreeSpin;
                    this._Round = session.Round;

                    //SupportedBaseEntity support = HiLoSession.LoadSupported(GameTriple7.Id, _AccountId, session.Id);
                    //if (support == null)
                    //{
                    //    support = new SupportedBaseEntity()
                    //    {
                    //        Jackpot = 0,
                    //        UsedCollect = 0,
                    //        UsedExtraLife = 0,
                    //        UsedFreeSpin = 0,
                    //        UsedNudges = 0,
                    //        UsedOutOf = 0
                    //    };
                    //}
                    //this._UsedExtraLife = support.UsedExtraLife;
                    //this._UsedOutOf = support.UsedOutOf;
                    //this._UsedNudges = support.UsedNudges;
                    //this._UsedFreeSpin = support.UsedFreeSpin;
                    //this._Jackpot = support.Jackpot;
                    //this._UsedCollect = support.UsedCollect;

                    this._Status = (Triple7Status)session.Status;
                }
                else
                {
                    _Status = Triple7Status.NewSession;
                    NewSession();
                }
            }
            else
            {
                throw new Exception("Trạng thái hiện tại không thể tải vòng chơi. (CurrentStatus: " + _Status.ToString() + ")");
            }
        }

        private void NewSession()
        {
            if (_Status == Triple7Status.NewSession)
            {
                _Status = Triple7Status.Bet;
            }
            else
            {
                throw new Exception("Trạng thái hiện tại không thể tạo vòng chơi mới. (CurrentStatus: " + _Status.ToString() + ")");
            }
        }

        private Triple7Status Win(int column, int colValue, Triple7Select select, int resultValue,
            int newCol1Value, int newCol2Value, int newCol3Value)
        {
            int bet = _AuCurrent;
            if (_AuCurrent == 0)
                bet = _AgCurrent;
            RateConfigEntity rateConfig = GetRate(bet);
            switch (column)
            {
                case 1:
                    if (select == Triple7Select.High)
                        bet = rateConfig.Column1WinForHigh;
                    else if (select == Triple7Select.Low)
                        bet = rateConfig.Column1WinForLow;
                    break;
                case 2:
                    if (select == Triple7Select.High)
                        bet = rateConfig.Column2WinForHigh;
                    else if (select == Triple7Select.Low)
                        bet = rateConfig.Column2WinForLow;
                    break;
                case 3:
                    if (select == Triple7Select.High)
                        bet = rateConfig.Column3WinForHigh;
                    else if (select == Triple7Select.Low)
                        bet = rateConfig.Column3WinForLow;
                    break;
            }

            int auBetCurr = _AuCurrent;
            int agBetCurr = _AgCurrent;
            if (auBetCurr > 0)
                auBetCurr = bet;
            else
                agBetCurr = bet;
            int round = _Round + 1;

            bool isJackpot = false;

            #region Jackpot
            _Jackpot = 0;
            if (newCol1Value == 7 && newCol2Value == 7 && newCol3Value == 7 &&
                //_UsedExtraLife == 0 && _UsedOutOf == 0 && _UsedNudges == 0 && _UsedFreeSpin == 0 && 
               (_AuBet >= GameTriple7.JackpotMinBetAu || _AgBet >= GameTriple7.JackpotMinBetAg) &&
               _Status == Triple7Status.SelectHiLo
               )
            {
                int jackpot = GameTriple7.JackpotAu + GameTriple7.JackpotAg;
                if (HiLoGame.ResetJackpot(GameTriple7.Id, true, true) > 0)
                {
                    GameTriple7.JackpotAu = GameTriple7.JackpotStartAu;
                    GameTriple7.JackpotAg = GameTriple7.JackpotStartAg;

                    isJackpot = true;

                    try
                    {
                        HiLoSession.AddAuAgAccount(_AccountId, GameTriple7.Id, jackpot, 0,
                        string.Format("Chơi game {0} trúng jackpot, được cộng {1} Au vào tài khoản.",
                        GameTriple7.Name, jackpot));

                        _Jackpot = jackpot;
                        //if (JackpotEventHandler != null)
                        //{
                        //    Triple7SessionInfo info = new Triple7SessionInfo()
                        //    {
                        //        AuBet = _AuBet,
                        //        AgBet = _AgBet,
                        //        AuCurrent = _AuCurrent,
                        //        AgCurrent = _AgCurrent,
                        //        Column1Value = newCol1Value,
                        //        Column2Value = newCol2Value,
                        //        Column3Value = newCol3Value,
                        //        Jackpot = jackpot,
                        //        Round = _Round,
                        //    };
                        //    new Thread(() => JackpotEventHandler(_AccountId, info)).Start();
                        //    //new Thread(() =>
                        //    //{
                        //    //    try
                        //    //    {
                        //    //        JackpotEventHandler(_AccountId, info);
                        //    //    }
                        //    //    catch
                        //    //    {
                        //    //    }
                        //    //}).Start();
                        //}
                    }
                    catch (Exception ex)
                    {
                        // log
                    }
                }
            }
            #endregion

            int r = HiLoSession.UpdateSession(_SessionId, _AccountId, _AccountName, _AccountTypeId, GameTriple7.Id,
                GameTriple7.Rate, GameTriple7.RandomRate, _AuBet, _AgBet, auBetCurr, agBetCurr,
                0, 0, 0, 0, isJackpot, false, round, "Thắng", 0, (int)Triple7Status.SelectHiLo);

            if (r <= 0)
                throw new Exception("Thao tác thất bại.");
            try
            {
                HiLoSessionDetail.InsertSessionDetail(_AccountId, GameTriple7.Id, _SessionId, _AuCurrent, _AgCurrent, auBetCurr, agBetCurr,
                    colValue, resultValue, (int)select, 1, false, false, false, false, isJackpot, false, round, (int)Triple7Status.SelectHiLo, "Thắng vòng chơi");
            }
            catch (Exception ex)
            {
                //Log lại 
            }

            _AuCurrent = auBetCurr;
            _AgCurrent = agBetCurr;
            _Round++;
            return Triple7Status.SelectHiLo;
        }

        private Triple7Status Lost(int column, int colValue, Triple7Select select, int resultValue)
        {
            int round = _Round + 1;

            if (_CurrentExtraLife > 0)
            {
                #region ExtraLife
                _CurrentExtraLife--;
                _UsedExtraLife++;

                int rExtraLife = HiLoSession.UpdateSession(_SessionId, _AccountId, _AccountName, _AccountTypeId, GameTriple7.Id,
                    GameTriple7.Rate, GameTriple7.RandomRate, _AuBet, _AgBet, _AuCurrent, _AgCurrent, 1, 0, 0, 0, false, false, round, "Sử dụng ExtraLife", 0, (int)_Status);

                if (rExtraLife == 0)
                    throw new Exception("Thao tác thất bại.");

                try
                {
                    HiLoSessionDetail.InsertSessionDetail(_AccountId, GameTriple7.Id, _SessionId, _AuCurrent, _AgCurrent, _AuCurrent, _AgCurrent,
                        colValue, resultValue, (int)select, 0, true, false, false, false, false, false, round, (int)_Status, "Sử dụng ExtraLife");
                }
                catch (Exception ex)
                {
                    //Log lại 
                }
                #endregion
                return Triple7Status.SelectHiLo;
            }
            else
            {
                int r = HiLoSession.UpdateSession(_SessionId, _AccountId, _AccountName, _AccountTypeId, GameTriple7.Id,
                GameTriple7.Rate, GameTriple7.RandomRate, _AuBet, _AgBet, 0, 0, 0, 0, 0, 0, false, false, round, "Thua", 0, 0);

                if (r <= 0)
                    throw new Exception("Thao tác thất bại.");
                try
                {
                    HiLoSessionDetail.InsertSessionDetail(_AccountId, GameTriple7.Id, _SessionId, _AuCurrent, _AgCurrent, 0, 0,
                        colValue, resultValue, (int)select, -1, false, false, false, false, false, false, round, 0, "Thua");
                }
                catch (Exception ex)
                {
                    //Log lại 
                }

                _CountConsecutiveWin = 0;

                ClearProperties();
                return Triple7Status.Bet;
            }
        }

        //-------------------------------------

        private void Bet(int auBet, int agBet)
        {
            try
            {
                ClearProperties();

                IsBusy = true;
                #region content
                if (_Status == Triple7Status.Bet)
                {
                    if (auBet != 0 && auBet < GameTriple7.MinimumBet)
                        throw new Exception("Số vàng đặt cược tối thiểu: " + GameTriple7.MinimumBet);
                    if (agBet != 0 && agBet < GameTriple7.MinimumBet)
                        throw new Exception("Số bạc đặt cược tối thiểu: " + GameTriple7.MinimumBet);

                    if (auBet > GameTriple7.MaximumBet)
                        throw new Exception("Số vàng đặt cược tối đa: " + GameTriple7.MaximumBet);

                    if (agBet > GameTriple7.MaximumBet)
                        throw new Exception("Số bạc đặt cược tối đa: " + GameTriple7.MaximumBet);

                    int sub = HiLoSession.SubAuAgAccount(_AccountId, GameTriple7.Id, auBet, agBet,
                        string.Format("Đặt cược {0} Au và {1} Ag vào game {2}", auBet, agBet, GameTriple7.Name));
                    if (sub > 0)
                    {
                        try
                        {
                            SessionBaseEntity session = HiLoSession.CreateSession(this._AccountId, this._AccountName, this._AccountTypeId,
                                GameTriple7.Id, GameTriple7.MinimumValue, GameTriple7.MaximumValue, GameTriple7.MinimumBet, GameTriple7.MaximumBet,
                                GameTriple7.Rate, GameTriple7.RandomRate, auBet, agBet, auBet, agBet,
                                GameTriple7.StartExtraLife, GameTriple7.StartOutOf, GameTriple7.StartNudges, GameTriple7.StartFreeSpin,
                                GameTriple7.ExtraLife, GameTriple7.OutOf, GameTriple7.Nudges, GameTriple7.FreeSpin,
                                GameTriple7.MaximumExtraLife, GameTriple7.MaximumOutOf, GameTriple7.MaximumNudges, GameTriple7.MaximumFreeSpin,
                                0, 0, (int)Triple7Status.SelectHiLo);

                            this._SessionId = session.Id;
                            this._AuBet = (int)session.AuBet;
                            this._AgBet = (int)session.AgBet;
                            this._AuCurrent = (int)session.AuCurrent;
                            this._AgCurrent = (int)session.AgCurrent;
                            this._CurrentExtraLife = session.CurrentExtraLife;
                            this._CurrentOutOf = session.CurrentOutOf;
                            this._CurrentNudges = session.CurrentNudges;
                            this._CurrentFreeSpin = session.CurrentFreeSpin;
                            this._Round = session.Round;

                            CreateRandomFor(out _Column1Value, out _Column2Value, out _Column3Value);

                            this._Status = Triple7Status.SelectHiLo;

                            _CountSession++;
                        }
                        catch (Exception ex)
                        {
                            HiLoSession.SubAuAgAccount(_AccountId, GameTriple7.Id, auBet, agBet,
                                string.Format("Trả tiền cược {0} Au và {1} Ag vào game {2} do lỗi khởi tạo game", auBet, agBet, GameTriple7.Name));
                            throw ex;
                        }
                    }
                    else
                    {
                        throw new Exception(string.Format("Không trừ đươc {0} Au và {1} Ag vào tài khoản {2}", auBet, agBet, _AccountId));
                    }
                }
                else
                {
                    throw new Exception("Trạng thái hiện tại không thể đặt cược. (CurrentStatus: " + _Status.ToString() + ")");
                }
                #endregion
            }
            finally
            {
                IsBusy = false;
            }
        }

        private RateConfigEntity GetRate(int betValue)
        {
            //if (_Status == Triple7Status.Bet)
            //{
            Dictionary<int, RateConfigTriple7Entity> dic = HiLoGame.GetRateConfigTriple7(GameTriple7.Rate, this._Column1Value);
            RateConfigTriple7Entity entity1 = dic[this._Column1Value];
            RateConfigTriple7Entity entity2 = dic[this._Column2Value];
            RateConfigTriple7Entity entity3 = dic[this._Column3Value];

            RateConfigEntity rateConfig = new RateConfigEntity()
            {
                Bet = betValue,
                Column1WinForHigh = (int)(entity1.WinForHigh * betValue),
                Column1WinForLow = (int)(entity1.WinForLow * betValue),
                Column2WinForHigh = (int)(entity2.WinForHigh * betValue),
                Column2WinForLow = (int)(entity2.WinForLow * betValue),
                Column3WinForHigh = (int)(entity3.WinForHigh * betValue),
                Column3WinForLow = (int)(entity3.WinForLow * betValue)
            };
            return rateConfig;
            //}
            //else
            //{
            //    throw new Exception("Trạng thái hiện tại không thể lấy cấu tỉ lệ. (CurrentStatus: " + _Status.ToString() + ")");
            //}
        }

        private void SelectHiLo(int column, Triple7Select select)
        {
            try
            {
                IsBusy = true;
                #region Content
                if (_Status == Triple7Status.SelectHiLo)
                {
                    int value1 = 0;
                    int value2 = 0;
                    int value3 = 0;

                    CreateRandomFor(out value1, out value2, out value3);

                    int colValue = 0;
                    int resultValue = 0;
                    switch (column)
                    {
                        case 1:
                            colValue = _Column1Value;
                            resultValue = value1;
                            break;
                        case 2:
                            colValue = _Column2Value;
                            resultValue = value2;
                            break;
                        case 3:
                            colValue = _Column3Value;
                            resultValue = value3;
                            break;
                        default:
                            throw new Exception(string.Format("Cột chọn không hợp lệ. Cột: {0}", column));
                    }

                    switch (select)
                    {
                        case Triple7Select.High:
                            if (resultValue > colValue)
                            {
                                // player win
                                _Status = Win(column, colValue, select, resultValue, value1, value2, value3);
                                UpdatePlayerSupport();
                            }
                            else
                            {
                                // PlayerLost
                                _Status = Lost(column, colValue, select, resultValue);
                            }

                            break;
                        case Triple7Select.Low:
                            if (resultValue < colValue)
                            {
                                // player win
                                _Status = Win(column, colValue, select, resultValue, value1, value2, value3);
                                UpdatePlayerSupport();
                            }
                            else
                            {
                                // PlayerLost
                                _Status = Lost(column, colValue, select, resultValue);
                            }
                            break;
                    }

                    _ResultValue = resultValue;
                    _Column1Value = value1;
                    _Column2Value = value2;
                    _Column3Value = value3;
                }
                else
                {
                    throw new Exception("Trạng thái hiện tại không thể chọn. (CurrentStatus: " + _Status.ToString() + ")");
                }
                #endregion
            }
            finally
            {
                IsBusy = false;
            }
        }

        private void Collect()
        {
            try
            {
                IsBusy = true;
                #region content
                if (_Status == Triple7Status.SelectHiLo && _Round > 0)
                {
                    int auBetCurr = _AuCurrent;
                    int agBetCurr = _AgCurrent;
                    int round = _Round;

                    int r = HiLoSession.UpdateSession(_SessionId, _AccountId, _AccountName, _AccountTypeId, GameTriple7.Id,
                        GameTriple7.Rate, GameTriple7.RandomRate, _AuBet, _AgBet, auBetCurr, agBetCurr,
                        0, 0, 0, 0, false, true, round, "Thắng", 0, (int)Triple7Status.Collect);
                    if (r > 0)
                    {
                        HiLoSession.AddAuAgAccount(_AccountId, GameTriple7.Id, auBetCurr, agBetCurr,
                            string.Format("Chơi game thắng {0} Au và {1} Ag từ game {2}. Được cộng vào tài khoản.",
                            auBetCurr, agBetCurr, GameTriple7.Name));

                        _Status = Triple7Status.Bet;

                        _CountWin++;
                        _CountConsecutiveWin++;
                    }
                    else
                        throw new Exception("Thao tác thất bại.");

                    try
                    {
                        HiLoSessionDetail.InsertSessionDetail(_AccountId, GameTriple7.Id, _SessionId, _AuCurrent, _AgCurrent, auBetCurr, agBetCurr,
                            0, 0, 3, 0, false, false, false, false, false, true, round, (int)Triple7Status.Collect, "Collect");
                    }
                    catch (Exception ex)
                    {
                        //Log lại 
                    }
                }
                else
                {
                    throw new Exception("Trạng thái hiện tại không thể collect. (CurrentStatus: " + _Status.ToString() + ")");
                }
                #endregion
                ClearProperties();
            }
            finally
            {
                IsBusy = false;
            }
        }

        #endregion

        #region Ho tro nguoi choi
        //------- Call by private method ------
        private bool AddNudges()
        {
            if (GameTriple7.Nudges == 0 || GameTriple7.MaximumNudges == 0)
                return false;

            if (_CurrentNudges < GameTriple7.MaximumNudges && _Round % GameTriple7.Nudges == 0)
            {
                int n = HiLoSession.UpdateSession(_SessionId, _AccountId, _AccountName, _AccountTypeId,
                           GameTriple7.Id, GameTriple7.Rate, GameTriple7.RandomRate, _AuBet, _AgBet, _AuCurrent, _AgCurrent,
                           0, 0, 1, 0, false, false, _Round, "+Nudges", 0, (int)_Status);
                if (n > 0)
                {
                    _CurrentNudges++;
                    try
                    {
                        HiLoSessionDetail.InsertSessionDetail(_AccountId, GameTriple7.Id, _SessionId, _AuCurrent, _AgCurrent,
                            _AuCurrent, _AgCurrent, 0, 0, (int)Triple7Select.None, 0, false, false, false, false, false, false, _Round, 1, "+Nudges");
                    }
                    catch (Exception ex)
                    {
                        //Log lại 
                    }
                    return true;
                }
            }
            return false;
        }
        //-------------------------------------

        /// <summary>
        /// Sau khi nguoi choi win 
        /// </summary>
        private void UpdatePlayerSupport()
        {
            try
            {
                IsBusy = true;
                AddNudges();
            }
            catch (Exception ex)
            {
                //log thoi
            }
            finally
            {
                IsBusy = false;
            }
        }

        private bool ExecuteNudges()
        {
            try
            {
                IsBusy = true;
                #region Content
                if (_CurrentNudges <= 0)
                    throw new Exception("Không đủ Nudges");
                int n = HiLoSession.UpdateSession(_SessionId, _AccountId, _AccountName, _AccountTypeId,
                    GameTriple7.Id, GameTriple7.Rate, GameTriple7.RandomRate, _AuBet, _AgBet, _AuCurrent, _AgCurrent,
                    0, 0, -1, 0, false, false, _Round, "-Nudges", 0, (int)_Status);
                if (n > 0)
                {
                    _CurrentNudges--;
                    _UsedNudges++;

                    CreateRandomFor(out _Column1Value, out _Column2Value, out _Column3Value);

                    try
                    {
                        HiLoSessionDetail.InsertSessionDetail(_AccountId, GameTriple7.Id, _SessionId, _AuCurrent, _AgCurrent,
                            _AuCurrent, _AgCurrent, 0, 0, (int)Triple7Select.None, 0, false, false, true, false, false, false, _Round, 1, "-Nudges");
                    }
                    catch (Exception ex)
                    {
                        //Log lại 
                    }
                    return true;
                }
                return false;
                #endregion
            }
            finally
            {
                IsBusy = false;
            }
        }

        #endregion

        #endregion Private method

        #region Contructor
        public HiLoTriple7(int accountId, string accountName, int accountType)
        {
            IsBusy = false;

            _AccountId = accountId;
            _AccountName = accountName;
            _AccountTypeId = accountType;

            _Status = Triple7Status.LoadGame;

            LoadGame();
            LoadSession();
        }
        #endregion Contructor

        #region Public method
        public RateConfigEntity GetRateConfig(int betValue)
        {
            return GetRate(betValue);
        }

        public int GetGameStatus()
        {
            return (int)_Status;
        }

        public int GetRound()
        {
            return _Round;
        }

        public int GetColumn1Value()
        {
            return _Column1Value;
        }

        public int GetColumn2Value()
        {
            return _Column2Value;
        }

        public int GetColumn3Value()
        {
            return _Column3Value;
        }

        public int GetAuBet()
        {
            return _AuBet;
        }

        public int GetAgBet()
        {
            return _AgBet;
        }

        public int GetAuCurrent()
        {
            return _AuCurrent;
        }

        public int GetAgCurrent()
        {
            return _AgCurrent;
        }

        public int GetLastValue()
        {
            return _ResultValue;
        }

        public int GetExtraLife()
        {
            return _CurrentExtraLife;
        }

        public int GetOutOf()
        {
            return _CurrentOutOf;
        }

        public int GetNudges()
        {
            return _CurrentNudges;
        }

        public int GetFreeSpin()
        {
            return _CurrentFreeSpin;
        }

        public int GetJackpot()
        {
            return _Jackpot;
        }

        public void PlayerBetAu(int auBet)
        {
            if (IsBusy)
                throw new Exception(string.Format("Đang xử lý, thao tác thất bại", _Status));

            if (auBet < GameTriple7.MinimumBet || auBet > GameTriple7.MaximumBet)
                throw new Exception(string.Format("Vàng đặt cược phải trong khoảng: {0} Au => {1} Au.", GameTriple7.MinimumBet, GameTriple7.MaximumBet));

            Bet(auBet, 0);
        }

        public void PlayerBetAg(int agBet)
        {
            if (IsBusy)
                throw new Exception(string.Format("Đang xử lý, thao tác thất bại", _Status));

            if (agBet < GameTriple7.MinimumBet || agBet > GameTriple7.MaximumBet)
                throw new Exception(string.Format("Bạc đặt cược phải trong khoảng: {0} Ag => {1} Ag.", GameTriple7.MinimumBet, GameTriple7.MaximumBet));
            Bet(0, agBet);
        }

        public void PlayerSelectHigh(int column)
        {
            if (IsBusy)
                throw new Exception(string.Format("Đang xử lý, thao tác thất bại", _Status));

            if (column <= 0 || column > 3)
                throw new Exception("Cột phải có giá trị từ 1 => 3");
            SelectHiLo(column, Triple7Select.High);
        }

        public void PlayerSelectLow(int column)
        {
            if (IsBusy)
                throw new Exception(string.Format("Đang xử lý, thao tác thất bại", _Status));

            if (column <= 0 || column > 3)
                throw new Exception("Cột phải có giá trị từ 1 => 3");
            SelectHiLo(column, Triple7Select.Low);
        }

        public void PlayerSelectNudges()
        {
            if (IsBusy)
                throw new Exception(string.Format("Đang xử lý, thao tác thất bại", _Status));

            if (_CurrentNudges <= 0)
                throw new Exception("Thao tác không hợp lệ.");
            ExecuteNudges();
        }

        public void PlayerCollect()
        {
            if (IsBusy)
                throw new Exception(string.Format("Đang xử lý, thao tác thất bại", _Status));

            if ((_AuBet == 0 && _AgBet == 0) || _Round == 0)
                throw new Exception("Thao tác này không hợp lệ.");

            Collect();
        }

        #endregion Public method

        #region enum
        private enum Triple7Status
        {
            None = 0,
            LoadGame = 1,
            LoadSession = 2,
            NewSession = 3,
            Bet = 4,
            SelectHiLo = 5,
            Collect = 6
        }

        private enum Triple7Select
        {
            None = 0,
            High = 1,
            Low = 2,
            Collect = 3,
            Nudges = 4,
            OutOf = 5,
            FreeSpin = 6,
            ExtraLife = 7
        }
        #endregion enum
    }
}
